//
//  ModuleFactory.h
//  sad
//
//  Created by Christopher Kemsley on 1/31/12.
//  Copyright (c) 2012 iAppolopolis. All rights reserved.
//

#ifndef sad_ModuleFactory_h
#define sad_ModuleFactory_h



#include <vector>
#include <string>
#include <map>
#include "URL.hpp"
#include "SystemCDefinitions.hpp"


class	ModuleFactory ;
class	ModuleMaker ;
class	ModuleVariant ;

#include "Model.hpp"




/*	Modules:
 
 Your constructor should take two arguments:
 
 sc_module_name const& name , URL const& path
 
 Use the "File" class to get other properties from the file path. Due
 to stupidity in SystemC, you must use the name object passed in as an
 argument.
 
 Declare the following maker in your file:
 
 TypedModuleMaker<YourType> YourTypeInstance ( "Clock" ) ;
 */



/*	Users:
 
 To create a module, simple call:
 
 ModuleFactory :: create ( aPath ) ;
 
 This extracts the variant and instance names from the files
 and [attempts to] construct the appropriate module.
 */





class	ModuleFactory
{
public:
	static Model*	create	( ModelVariant const & variant ) ;
	
	
protected:
	friend class ModuleMaker ;
	static std::map<std::string,ModuleMaker*>&	makers () ;
} ;











class	ModuleMaker
{
protected:
	friend class ModuleFactory ;
	
	ModuleMaker ( char const* name ) ;
	
	virtual Model*		create	( ModelVariant const & identity ) = 0 ;
} ;



template <class Type>
class	TypedModuleMaker : public ModuleMaker
{
public:
	TypedModuleMaker ( char const* name ) : ModuleMaker(name) {  }
	~TypedModuleMaker () { }
	
	virtual Model*		create	( ModelVariant const & identity )
		{
		return new Type ( identity ) ;
		}
} ;


#endif
